package com.bygf.curve.axis;

import com.bygf.curve.panel.ChartPanel;
import com.bygf.curve.utils.Utils;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.text.DecimalFormat;

/**
 * X坐标轴
 *
 * @author sunyupei
 */
public class XAxis extends Axis {

    //坐标格式化对象
    private DecimalFormat format = new DecimalFormat("#");

    /**
     * 构造方法
     *
     * @param chartPanel
     * @param title 坐标轴标题
     */
    public XAxis(ChartPanel chartPanel, String title) {
        this.chartPanel = chartPanel;
        this.title = title;
        this.setOpaque(false);
    }

    /**
     * 绘制坐标轴标题
     *
     * @param g
     */
    private void drawTitle(Graphics2D g) {
        g.setColor(titleColor);
        int titleWidht = Utils.getStringWidth(title, null);
        g.drawString(title, (this.getWidth() - titleWidht) / 2, 35);
    }

    /**
     * 绘制刻度线及刻度单位
     *
     * @param g
     */
    private void drawMarkLine(Graphics2D g) {
        drawStart = chartPanel.getXAxisDrawBeginPix();
        drawEnd = chartPanel.getXAxisDrawEndPix();
        g.setColor(lineColor);
        g.drawLine(drawStart, 1, drawEnd, 1);
        double mark = (drawEnd - drawStart) * 1F / chartPanel.getXGridLineCount();
        double valueMark = (getEndValueNow() - getStartValueNow()) / chartPanel.getXGridLineCount();
        for (int i = 0; i <= chartPanel.getXGridLineCount(); i++) {
            Line2D line = new Line2D.Double(drawStart + mark * i, 1, drawStart + mark * i, 6);
            g.draw(line);
            String str = format.format(valueMark * i + getStartValueNow());
            float x = (float) ((drawStart + mark * i) - Utils.getStringWidth(str, titleFont) / 2);
            g.drawString(str, x, 20);
        }
    }

    /**
     * 双缓冲绘制
     *
     * @param g
     */
    private void doubleBuffer(Graphics2D g) {
        g.setColor(Color.BLACK);
        g.setStroke(new BasicStroke(1F));
        drawTitle(g);
        drawMarkLine(g);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        BufferedImage bufferedImage = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = bufferedImage.createGraphics();
        RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//        rh.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
        rh.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
        rh.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
        rh.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        g2.setRenderingHints(rh);
        doubleBuffer(g2);
        g.drawImage(bufferedImage, 0, 0, null);
    }

    @Override
    public double valueToPix(double value) {
        return (value - getStartValueNow()) / (getEndValueNow() - getStartValueNow()) * chartPanel.getCurvePanel().getWidth();
    }

    @Override
    public double PixToValue(double pix) {
        return pix / chartPanel.getCurvePanel().getWidth() * (getEndValueNow() - getStartValueNow()) + getStartValueNow();
    }

    /**
     * @return the format
     */
    public DecimalFormat getDecimalFormat() {
        return format;
    }

    /**
     * @param format the format to set
     */
    public void setDecimalFormat(DecimalFormat format) {
        this.format = format;
    }

    @Override
    public boolean setValueCheck(double startValueNow, double endValueNow) {
        double valueCha = (endValueNow - startValueNow) / chartPanel.getXGridLineCount();
        double minCha = 1D / Math.pow(10, format.getMaximumFractionDigits());
        return valueCha >= minCha;
    }
    
    @Override
    public void setStartValueNow(double startValueNow) {
        this.startValueNow = Double.parseDouble(format.format(startValueNow));
        this.repaint();
        if (listener != null) {
            listener.axisChanged(this);
        }
    }
    
    @Override
    public void setEndValueNow(double endValueNow) {
        this.endValueNow = Double.parseDouble(format.format(endValueNow));
        this.repaint();
        if (listener != null) {
            listener.axisChanged(this);
        }
    }
}
